import { locations } from "../../../gpu/locations";
export const Animation = /*wgsl*/ `
#if ~{def.u_MorphTargetsSampler}
@group(${locations.u_MorphTargetsSampler[0]}) @binding(${locations.u_MorphTargetsSampler[1]}) var u_MorphTargetsSampler :texture_2d_array<f32>;
#endif 
#if ~{def.u_morphWeights}
// @group(${locations.u_morphWeights[0]}) @binding(${locations.u_morphWeights[1]}) var<uniform> u_morphWeights : vec~{def.WEIGHT_COUNT}<f32>;
@group(${locations.u_morphWeights[0]}) @binding(${locations.u_morphWeights[1]}) var<storage, read> u_morphWeights : array<f32>;
#endif
#if ~{def.u_jointsSampler}
@group(${locations.u_jointsSampler[0]}) @binding(${locations.u_jointsSampler[1]}) var<uniform> u_jointsSampler : texture_2d;
#endif 

#if ~{def.u_jointsSampler}
fn skinMatrix( s:texture_2d, index:u32)->mat4x4<f32>{
    var result:mat4x4<f32> = mat4(1);
    var texSize:u32 = textureDimensions(s, 0)[0];
    var pixelIndex:u32 = index * 4;
    for (let i:u32 = 0; i < 4; ++i){
        var x:u32 = (pixelIndex + i) % texSize;
        var y:u32 = (pixelIndex + i - x) / texSize; 
        result[i] = textureLoad(s, vec2<u32>(x,y), 0);
    }
    return result;
}
fn fullMatrix(input:VertexInput)->mat4x4<f32>{
    var skin:mat4x4<f32> = mat4(0);
    #if ~{def.weights0&&def.joints0}
    skin +=
        input.weights0.x * skinMatrix(u_jointsSampler, int(input.joints0.x) * 2) +
        input.weights0.y * skinMatrix(u_jointsSampler, int(input.joints0.y) * 2) +
        input.weights0.z * skinMatrix(u_jointsSampler, int(input.joints0.z) * 2) +
        input.weights0.w * skinMatrix(u_jointsSampler, int(input.joints0.w) * 2);
    #endif
    #if ~{def.weight1&&def.joints1}
    skin +=
        input.weights1.x * skinMatrix(u_jointsSampler, int(input.joints1.x) * 2) +
        input.weights1.y * skinMatrix(u_jointsSampler, int(input.joints1.y) * 2) +
        input.weights1.z * skinMatrix(u_jointsSampler, int(input.joints1.z) * 2) +
        input.weights1.w * skinMatrix(u_jointsSampler, int(input.joints1.w) * 2);
    #endif
    if (skin == mat4(0)) { 
        return mat4(1); 
    }
    return skin;
}


fn skinNormalMatrix()->mat4x4<f32>{
  var skin:mat4x4<f32> = mat4(0);
  #if ~{def.weights0&&def.joints0}
    skin +=
    input.weights0.x * skinMatrix(u_jointsSampler, int(input.joints0.x) * 2 + 1) +
    input.weights0.y * skinMatrix(u_jointsSampler, int(input.joints0.y) * 2 + 1) +
    input.weights0.z * skinMatrix(u_jointsSampler, int(input.joints0.z) * 2 + 1) +
    input.weights0.w * skinMatrix(u_jointsSampler, int(input.joints0.w) * 2 + 1);
  #endif

  #if ~{def.weight1&&def.joints1}
    skin +=
    input.weights1.x * skinMatrix(u_jointsSampler, int(input.joints1.x) * 2 + 1) +
    input.weights1.y * skinMatrix(u_jointsSampler, int(input.joints1.y) * 2 + 1) +
    input.weights1.z * skinMatrix(u_jointsSampler, int(input.joints1.z) * 2 + 1) +
    input.weights1.w * skinMatrix(u_jointsSampler, int(input.joints1.w) * 2 + 1);
  #endif
    if (skin == mat4(0)) { 
        return mat4(1); 
    }
    return skin;
 }
#endif 

#if ~{def.u_morphWeights}

#if ~{def.u_MorphTargetsSampler}
fn textureOffset( id:u32,  arrayIndex:u32,  size:u32)->vec4<f32>{
    var x:u32 = id % size;
    var y:u32 = (id - x) / size; 
    // var y:u32 = (vertexID - x) ; 
    return textureLoad(u_MorphTargetsSampler, vec2<u32>(x, y), arrayIndex,0);
}
#endif


fn morphPosition( id:u32)->vec4<f32>{
    var pos:vec4<f32> = vec4(0);
    var texSize:u32 = textureDimensions(u_MorphTargetsSampler, 0)[0];
    // 不要删除后面可能需要用
    // var depth:u32 = textureNumLayers(u_MorphTargetsSampler);
    for(var i:u32 = 0; i <~{def?.WEIGHT_COUNT}; i++){
      var offset:vec4<f32> = textureOffset(id, ~{def?.morphPositionOffset} + i, texSize);
      pos += u_morphWeights[i] * offset;
    }
    return pos;
}

fn morphNormal( id:u32)->vec3<f32>{
    var normal:vec3<f32> = vec3(0);
   #if ~{def.morphNormalOffset}
    var texSize:u32 = textureDimensions(u_MorphTargetsSampler, 0)[0];
    for(var i:u32 = 0; i < ~{def?.WEIGHT_COUNT}; i++){
      var offset:vec3<f32> = textureOffset(id, ~{def?.morphNormalOffset} + i, texSize).xyz;
        normal += u_morphWeights[i] * offset;
    }
#endif
    return normal;
}


fn morphTangent(id:u32)->vec3<f32>{
    var tangent:vec3<f32> = vec3(0);
   #if ~{def.morphTangentOffset}
    var texSize:u32 = textureDimensions(u_MorphTargetsSampler, 0)[0];
    for(var i:u32 = 0; i < ~{def?.WEIGHT_COUNT}; i++){
        var offset:vec3<f32> = textureOffset(id, ~{def?.morphTangentOffset} + i, texSize).xyz;
        tangent += u_morphWeights[i] * offset;
    }
#endif
    return tangent;
}

fn morphTexCoord0(id:u32)->vec2<f32>
{
     var uv:vec2<f32> = vec2(0);
    #if ~{def.morphTexcoordOffset}
    var texSize:u32 = textureDimensions(u_MorphTargetsSampler, 0)[0];
    for(var i:u32 = 0; i < ~{def?.WEIGHT_COUNT}; i++){
        var offset:vec2<f32> = textureOffset(id, ~{def?.morphTexcoordOffset} + i, texSize).xy;
        uv += u_morphWeights[i] * offset;
    }
    #endif
    return uv;
}

fn morphTexCoord1(id:u32)->vec2<f32>
{
    var uv:vec2<f32> = vec2(0);
    #if ~{def.morphTexcoord1Offset}
    var texSize:u32 = textureDimensions(u_MorphTargetsSampler, 0)[0];
    for(let i:u32 = 0; i < ~{def?.WEIGHT_COUNT}; i++){
      var offset:vec2<f32>  = textureOffset(id, ~{def?.morphTexcoord1Offset} + i, texSize).xy;
        uv += u_morphWeights[i] * offset;
    }
#endif
    return uv;
}

fn morphColor0(id:u32)->vec4<f32>
{
    var color:vec4<f32> = vec4(0);
    #if ~{def.morphColor0Offset}
    var texSize:u32 = textureDimensions(u_MorphTargetsSampler, 0)[0];
    for(let i:u32 = 0; i < ~{def?.WEIGHT_COUNT}; i++){
        var offset:vec4<f32> = textureOffset(id, ~{def?.morphColor0Offset} + i, texSize);
        color += u_morphWeights[i] * offset;
    }
#endif
    return color;
}
#endif 
`;